from flask_restful import fields, abort
from flask_restful import Resource, reqparse, Api, marshal_with
from models import Community_PostModel, PostComment, PostLike
from flask import Blueprint, request, current_app, g
from exts import db
import os
import json
from werkzeug.datastructures import FileStorage
from datetime import datetime
from functools import wraps

post_api_bp = Blueprint('post_api', __name__)
api = Api(post_api_bp)

# 定义返回字段格式
post_fields = {
    'id': fields.Integer,
    'title': fields.String,
    'content': fields.String,
    'images': fields.List(fields.String),
    'user_id': fields.Integer,
    'create_time': fields.DateTime,
    'like_count': fields.Integer,
    'comment_count': fields.Integer,
    'post_type': fields.String,
    'partner_type': fields.String,
    'community_type': fields.String,
    'lost_found_type': fields.String
}

# 添加帖子列表的返回字段
post_list_fields = {
    'id': fields.Integer,
    'title': fields.String,
    'content': fields.String,
    'images': fields.List(fields.String),
    'user_id': fields.Integer,
    'create_time': fields.DateTime,
    'like_count': fields.Integer,
    'comment_count': fields.Integer,
    'post_type': fields.String,
    'partner_type': fields.String,
    'community_type': fields.String,
    'lost_found_type': fields.String
}

# 添加评论的返回字段格式
comment_fields = {
    'id': fields.Integer,
    'content': fields.String,
    'user_id': fields.Integer,
    'create_time': fields.DateTime
}

# 扩展帖子详情的返回字段
post_detail_fields = {
    'id': fields.Integer,
    'title': fields.String,
    'content': fields.String,
    'images': fields.List(fields.String),
    'user_id': fields.Integer,
    'create_time': fields.DateTime,
    'like_count': fields.Integer,
    'comment_count': fields.Integer,
    'post_type': fields.String,
    'partner_type': fields.String,
    'community_type': fields.String,
    'lost_found_type': fields.String,
    'comments': fields.List(fields.Nested(comment_fields)),  # 嵌套评论列表
    'is_liked': fields.Boolean  # 当前用户是否点赞
}

def abort_if_post_doesnt_exist(id):
    post = Community_PostModel.query.get(id)
    if not post:
        abort(404, message='Post not found')

# 更新解析器，添加图片支持
user_post_parser = reqparse.RequestParser()
user_post_parser.add_argument('title', type=str, required=True, help='标题不能为空', location='form')
user_post_parser.add_argument('content', type=str, required=True, help='内容不能为空', location='form')
user_post_parser.add_argument('images', type=FileStorage, location='files', action='append')
user_post_parser.add_argument('post_type', type=str, required=True, help='帖子类型不能为空', location='form')
user_post_parser.add_argument('partner_type', type=str, location='form')
user_post_parser.add_argument('community_type', type=str, location='form')
user_post_parser.add_argument('lost_found_type', type=str, location='form')

class Post(Resource):
    @marshal_with(post_fields)
    def get(self, post_id):
        post = Community_PostModel.query.get(post_id)
        abort_if_post_doesnt_exist(post_id)
        # 反序列化images字段
        if post.images:
            post.images = json.loads(post.images)
        return post

    def post(self, user_id):
        data = user_post_parser.parse_args()
        
        # 验证帖子类型
        if data['post_type'] not in ['partner', 'lost_found', 'community']:
            abort(400, message='无效的帖子类型')

        # 处理特定类的验证
        if data['post_type'] == 'partner':
            if not data['partner_type']:
                abort(400, message='搭子类型不能为空')
            if data['partner_type'] not in ['entertainment', 'sports', 'study', 'travel', 'others']:
                abort(400, message='无效的搭子类型')
                
        elif data['post_type'] == 'community':
            if not data['community_type']:
                abort(400, message='社区类型不能为空')
            # TODO: 验证社区类型是否有效
            
        elif data['post_type'] == 'lost_found':
            if not data['lost_found_type']:
                abort(400, message='失物招领类型不能为空')
            if data['lost_found_type'] not in ['lost', 'found']:
                abort(400, message='无效的失物招领类型')
                
        print(data['images'])
        image_paths = []
        if data['images']:
            for image in data['images']:
                if image and self._allowed_file(image.filename):
                    filename = self._secure_filename(image.filename)
                    image_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
                    image.save(image_path)
                    image_paths.append(filename)

        # 创建帖子
        post = Community_PostModel(
            title=data['title'],
            content=data['content'],
            user_id=user_id,
            images=json.dumps(image_paths) if image_paths else None,
            create_time=datetime.now(),
            post_type=data['post_type'],
            partner_type=data.get('partner_type'),
            community_type=data.get('community_type'),
            lost_found_type=data.get('lost_found_type')
        )
        
        db.session.add(post)
        db.session.commit()
        return {'id': post.id}, 201

    def _allowed_file(self, filename):
        return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'png', 'jpg', 'jpeg', 'gif'}

    def _secure_filename(self, filename):
        import uuid
        ext = filename.rsplit('.', 1)[1].lower()
        return f"{str(uuid.uuid4())}.{ext}"

    def delete(self, post_id, user_id):
        post = Community_PostModel.query.get(post_id)
        abort_if_post_doesnt_exist(post_id)
        
        # 验证是否是帖子作者在删除
        if post.user_id != user_id:
            abort(403, message='Permission denied')
            
        # 删除相关的图片文件
        if post.images:
            for image in json.loads(post.images):
                try:
                    image_path = os.path.join(current_app.config['UPLOAD_FOLDER'], image)
                    if os.path.exists(image_path):
                        os.remove(image_path)
                except Exception as e:
                    current_app.logger.error(f"Error deleting image {image}: {str(e)}")
        
        # 删除相关的点赞和评论
        PostLike.query.filter_by(post_id=post_id).delete()
        PostComment.query.filter_by(post_id=post_id).delete()
        
        db.session.delete(post)
        db.session.commit()
        return {'message': 'Post deleted'}

class PostLikeResource(Resource):
    def post(self, post_id, user_id):
        post = Community_PostModel.query.get(post_id)
        abort_if_post_doesnt_exist(post_id)
        
        like = PostLike.query.filter_by(post_id=post_id, user_id=user_id).first()
        if like:
            return {'message': 'Already liked'}, 400
            
        like = PostLike(post_id=post_id, user_id=user_id)
        db.session.add(like)
        post.like_count += 1
        db.session.commit()
        return {'message': 'Liked successfully'}

class PostCommentResource(Resource):
    def post(self, post_id, user_id):
        parser = reqparse.RequestParser()
        parser.add_argument('content', type=str, required=True)
        data = parser.parse_args()
        
        post = Community_PostModel.query.get(post_id)
        abort_if_post_doesnt_exist(post_id)
        
        comment = PostComment(
            content=data['content'],
            post_id=post_id,
            user_id=user_id,
            create_time=datetime.now()
        )
        db.session.add(comment)
        post.comment_count += 1
        db.session.commit()
        return {'id': comment.id}, 201

class PostList(Resource):
    @marshal_with(post_list_fields)
    def post(self):
        try:
            # 获取 JSON 数据
            data = request.get_json()
            
            # 设置默认值
            page = data.get('page', 1)
            per_page = data.get('per_page', 10)
            post_type = data.get('post_type')

            # 构建查询
            query = Community_PostModel.query

            # 根据类型筛选
            query = query.filter_by(post_type=post_type) 

            # 按时间倒序排序并分页
            posts = query.order_by(Community_PostModel.create_time.desc()).paginate(page=page, per_page=per_page, error_out=False)

            return posts.items
            
        except Exception as e:
            return {'error': str(e)}, 400

class PostDetail(Resource):
    @marshal_with(post_detail_fields)
    def post(self, post_id):
        try:
            # 获取请求数据（用户ID）
            data = request.get_json()
            current_user_id = data.get('user_id')  # 当前查看帖子的用户ID
            
            # 获取帖子信息
            post = Community_PostModel.query.get(post_id)
            if not post:
                abort(404, message='帖子不存在')
                
            # 获取评论列表
            comments = PostComment.query.filter_by(post_id=post_id)\
                .order_by(PostComment.create_time.desc()).all()
                
            # 检查当前用户是否点赞
            is_liked = False
            if current_user_id:
                like = PostLike.query.filter_by(
                    post_id=post_id,
                    user_id=current_user_id
                ).first()
                is_liked = like is not None
                
            # 构建返回数据
            result = {
                'id': post.id,
                'title': post.title,
                'content': post.content,
                'images': json.loads(post.images) if post.images else [],
                'user_id': post.user_id,
                'create_time': post.create_time,
                'like_count': post.like_count,
                'comment_count': post.comment_count,
                'post_type': post.post_type,
                'partner_type': post.partner_type,
                'community_type': post.community_type,
                'lost_found_type': post.lost_found_type,
                'comments': comments,
                'is_liked': is_liked
            }
            
            return result
            
        except Exception as e:
            return {'error': str(e)}, 400

api.add_resource(Post, 
    '/post/create/<int:user_id>',  # 用于创建帖子
    '/post/get/<int:post_id>',     # 用于获取帖子
    '/post/delete/<int:post_id>/<int:user_id>'   # 修改删除帖子的路由
)


# TODO: 添加帖子列表接口
# TODO: 添加帖子详情接口
# TODO: 添加评论接口
# TODO: 添加点赞接口
